/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * BankSummary.java
 *
 * Created on May 25, 2009, 11:13:42 AM
 */

package viewer.mortgage;
import Bank.Bank;
import MortgageCore.*;
import TableUtils.VerticalTableHeaderCellRenderer;
import javax.swing.table.AbstractTableModel;
import javax.swing.JTable;
import java.awt.Dimension;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.util.Enumeration;
import javax.swing.table.TableColumnModel;
import javax.swing.table.DefaultTableCellRenderer;
import simframe.simulation.SimViewer;
import java.awt.Color;

/**
 *
 * @author karakots
 */
public class BankSummary extends javax.swing.JFrame implements SimViewer {
    SavingsSim ss;
    final int countWidth = 25;
    final int moneyWidth = 45;
    final int nameWidth = 200;
    final int pctWidth = 35;
    private boolean showQuarter = false;



    /** Creates new form BankSummary */
    public BankSummary(SavingsSim SavingsSim) {
        initComponents();
        showQuarter(false);


        ss = SavingsSim;
        bankInfoTable.setModel(new MyTableModel());
        int windowWidth  = nameWidth + (6*countWidth) + (6*moneyWidth) + (12*pctWidth) + 2;
        setSize(windowWidth, 360);
        bankInfoTable.setPreferredScrollableViewportSize(new Dimension(windowWidth, 70));
        bankInfoTable.setFillsViewportHeight(true);
        bankInfoTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        bankInfoTable.getTableHeader().setPreferredSize(new Dimension(20, 120));

        TableCellRenderer headerRenderer = new VerticalTableHeaderCellRenderer();
        Enumeration columns = bankInfoTable.getColumnModel().getColumns();
        while (columns.hasMoreElements()) {
            ((TableColumn) columns.nextElement()).setHeaderRenderer(headerRenderer);
        }
        setColWidths();
        reset();
    }

    private void showQuarter(boolean b) {
        showQuarter = b;
        entireSimulationButton.setSelected(!b);
        previousQuarterButton.setSelected(b);

    }

    public void reset() {
    }

    public void update(long t) {
       repaint();
    }

    public class PctRenderer extends DefaultTableCellRenderer {

        @Override
        public void setHorizontalAlignment(int alignment) {
            super.setHorizontalAlignment(alignment);
        }
    }

    // so we can draw negative numers in red
    public class DblRenderer extends DefaultTableCellRenderer {

        @Override
        public void setHorizontalAlignment(int alignment) {
            super.setHorizontalAlignment(alignment);
        }

        @Override
        public void setText(String t) {
            // strip percent sign
            int sl = t.length();
            if (sl > 1) {
                //String sdv = t.substring(0, sl-1);
                double dv = Double.parseDouble(t);
                if (!(this.getForeground().equals(Color.WHITE))) {
                    if (dv >= 0)
                        this.setForeground(Color.BLACK);
                    else
                        this.setForeground(Color.RED);
                }
            }
            super.setText(t);
        }
    }

    
    // so we can draw negative numers in red
    public class NameRenderer extends DefaultTableCellRenderer {

        @Override
        public void setHorizontalAlignment(int alignment) {
            super.setHorizontalAlignment(alignment);
        }

        @Override
        public void setText(String t) {
            int sl = t.length();
            if (sl > 1) {
                String lastChar = t.substring(sl - 1, sl);
                boolean failed = lastChar.matches("X");
                if (!(this.getForeground().equals(Color.WHITE))) {
                    if (failed) {
                        this.setForeground(Color.RED);
                    } else {
                        this.setForeground(Color.BLACK);
                    }
                }
                String finalName;
                if (failed) {
                    finalName = t.substring(0, sl - 2);
                } else {
                    finalName = t;
                }
                super.setText(finalName);
            }
            else
                super.setText(t);
        }
    }


    private enum Col {

        BANKNAME, DEPOSITS, LOANS, CASH, AVAIL2LOAN, EQUITY, SAVINGSINT,
        NUMOFFEREDLOANS, NUMPREAPPROVEDLOANS, NUMFUNDEDLOANS, NUMPAIDOFFLOANS, NUMLOANSDEFAULT, AVGLOANSIZE,
        YEARLOANS15, YEARLOANS30, LOANINTRATE, LOANPOINTS, MINDOWNPAYMENT, MAXPYMT2INCOME,
        MAXLOANSIZE, NUMLOANAPPLICATIONS, PCTAPPSQUALIFYING, PCTDOWNTOOLOW, PCTINCOMETOOLOW,
        PCTLOANTOOLARGE
    }

    private void setColWidths() {
        int colNum = 0;
        TableColumnModel cm = bankInfoTable.getColumnModel();
        for (Col col : Col.values()) {
            switch (col) {
                case BANKNAME:
                    setupNameCol(cm, colNum);
                    //cm.getColumn(colNum).setPreferredWidth(nameWidth);
                    break;
                case NUMFUNDEDLOANS:
                case NUMPREAPPROVEDLOANS:
                case NUMPAIDOFFLOANS:
                case NUMLOANSDEFAULT:
                case YEARLOANS15:
                case YEARLOANS30:
                    cm.getColumn(colNum).setPreferredWidth(countWidth);
                    break;
                case DEPOSITS:
                case LOANS:
                case CASH:
                case AVAIL2LOAN:
                case EQUITY:
                case MAXLOANSIZE:
                    setupDblCol(cm, colNum);
                    break;
                case SAVINGSINT:
                case LOANINTRATE:
                case LOANPOINTS:
                case MINDOWNPAYMENT:
                case MAXPYMT2INCOME:
                case PCTAPPSQUALIFYING:
                case PCTDOWNTOOLOW:
                case PCTINCOMETOOLOW:
                case PCTLOANTOOLARGE:
                case NUMLOANAPPLICATIONS:   // this is a count, not a prcent, but it is a larger number
                case NUMOFFEREDLOANS:
                case AVGLOANSIZE:           // this is a dollar number, but not that big
                    setupPctCol(cm, colNum);
                    break;
                default:
            }
            colNum++;
        }
    }

    // so we can get right alignmrnt on the pct columns,
    // which we render as text, we create a custom table cell renderer (PctRenderer)
    // in which we override the alignment only
    private void setupPctCol(TableColumnModel cm, int colNum) {
        cm.getColumn(colNum).setPreferredWidth(pctWidth);
        PctRenderer p = new PctRenderer();
        p.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        cm.getColumn(colNum).setCellRenderer(p);
    }

    private void setupDblCol(TableColumnModel cm, int colNum) {
        cm.getColumn(colNum).setPreferredWidth(moneyWidth);
        DblRenderer d = new DblRenderer();
        d.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        cm.getColumn(colNum).setCellRenderer(d);
    }

    private void setupNameCol(TableColumnModel cm, int colNum) {
        cm.getColumn(colNum).setPreferredWidth(nameWidth);
        NameRenderer n = new NameRenderer();
        n.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        cm.getColumn(colNum).setCellRenderer(n);
    }


    class MyTableModel extends AbstractTableModel {

        // use html tags so that text wraps, if necessary
        private String[] columnNames = {
            "<html><b/>Bank</html>",
            "<html><b/>Deposits $K</html>",
            "<html><b/>Loans $K</html>",
            "<html><b/>Cash $K</html>",
            "<html><b/>Available to Loan $K</html>",
            "<html><b/>Equity $K</html>",
            "<html><b/>Savings Int. Rate</html>",
            "<html><b/># Loans Offered</html>",
            "<html><b/># Loans Approved</html>",
            "<html><b/># Loans Funded </html>",
            "<html><b/># Paid Loan Paid Off</html>",
            "<html><b/># Loans in Default</html>",
            "<html><b/>Avgerage Loan Size $K</html>",
            "<html><b/>15 Year Loans</html>",
            "<html><b/>30 Year Loans</html>",
            "<html><b/>Loan Interest Rate</html>",
            "<html><b/>Loan Points</html>",
            "<html><b/>Min Down Payment</html>",
            "<html><b/>Max Payment:Income</html>",
            "<html><b/>Max Loan Size</html>",
            "<html><b/># Loan Applications</html>",
            "<html><b/>% Apps Qualifying</html>",
            "<html><b/>% Down too Low</html>",
            "<html><b/>% Income too Low</html>",
            "<html><b/>% Loan too Large</html>"
        };

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return ss.banks.size();
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            //return data[row][col];
            // for each bank (row)

            Bank bank = ss.banks.getAtIndex(row);
            for (Col x : Col.values()) {
                if (x.ordinal() == col) {
                    switch (x) {
                        case BANKNAME:
                            return bank.name;
                        case DEPOSITS: {
                            if (showQuarter)
                                return (int) bank.getLastQtrDeposits()/1000;
                            else
                                return (int) bank.getDeposits()/1000;
                        }
                        case LOANS: {
                            if (showQuarter)
                                return (int) bank.getLastQtrLoanBalanceOutstanding()/1000;
                            else
                                return (int) bank.getLoanBalanceOutstanding()/1000;
                        }
                        case CASH: {
                            if (showQuarter)
                                return (int) bank.getLastQtrCash()/1000;
                            else
                                return (int) bank.getCashAssets()/1000;
                        }
                        case AVAIL2LOAN: {
                            if (showQuarter)
                                return (int) bank.getLastQtrAmountAvialableToLoan()/1000;
                            else
                                return (int) bank.getAmountAvialableToLoanExcludingOffers()/1000;
                        }
                        case EQUITY:
                            if (showQuarter)
                                return (int) bank.getLastQtrEquity()/1000;
                            else
                                return (int) bank.getEquity()/1000;
                        case SAVINGSINT: {
                            double rate = 100 * 12 * bank.getSavingsMonthlyInterestRate();
                            String rateStr = String.format("%3.2f",rate);
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        case NUMFUNDEDLOANS:
                            if (showQuarter)
                                return bank.getNumLoansFundedThisQtr();
                            else
                                return bank.getNumLoansEverFunded();
                        case AVGLOANSIZE:
                            if (showQuarter)
                                return (int) (bank.getAverageLoanSizeThisQtr()/1000);
                            else
                                return (int) (bank.getAverageLoanSize()/1000);
                        case NUMOFFEREDLOANS:
                            if (showQuarter)
                                return (int) bank.getNumLoansOfferedThisQtr();
                            else
                                return (int) bank.getNumLoansEverOffered();
                        case NUMPREAPPROVEDLOANS:
                            if (showQuarter)
                                return bank.getNumLoansPreapprovedThisQtr();
                            else
                                return bank.getNumLoansEverPreapproved();
                        case NUMPAIDOFFLOANS:
                            if (showQuarter)
                                return bank.getNumLoansPaidOffThisQtr();
                            else
                                return bank.getNumLoansPaidOff();
                        case NUMLOANAPPLICATIONS:
                            if (showQuarter)
                                return (int) bank.getNumLoanApplicationsThisQtr();
                            else
                                return (int) bank.getNumLoanApplications();
                        case NUMLOANSDEFAULT:
                            if (showQuarter)
                                return bank.getNumDefaultsThisQtr();
                            else
                                return bank.getNumDefaultsEver();
                        case YEARLOANS15:
                            return bank.getLendingPolicy().loanLength15years;
                        case YEARLOANS30:
                            return bank.getLendingPolicy().loanLength30years;
                        case LOANINTRATE: {
                            double rate = 100 * 12 * bank.getLendingPolicy().monthlyMortgageInterestRate;
                            String rateStr = String.format("%3.1f",rate);
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        case LOANPOINTS: {
                            double rate = 100 * bank.getLendingPolicy().mortgagePoints;
                            String rateStr = String.format("%3.1f",rate);
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        case MINDOWNPAYMENT: {
                            double rate = 100 * bank.getLendingPolicy().minMortgagePctDown;
                            String rateStr = String.format("%3.1f",rate);
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        case MAXPYMT2INCOME: {
                            double rate = 100 * bank.getLendingPolicy().maxPaymentToIncome;
                            String rateStr = String.format("%3.1f",rate);
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        case MAXLOANSIZE:
                            return (int) bank.getLendingPolicy().maxLoanSize/1000;
                        case PCTAPPSQUALIFYING: {
                            double val;
                            if (showQuarter)
                                val =  bank.getPctLoanAppsQualifyingThisQtr();
                            else
                                val=  bank.getPctLoanAppsQualifying();
                            String rateStr = String.format("%4.0f",(val*100));
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        case PCTDOWNTOOLOW:{
                            double val;
                            if (showQuarter)
                                val = bank.getLendingPolicy().getQtrChgPctRejectedPctDown();
                            else
                                 val = bank.getLendingPolicy().getPctRejectedPctDown();
                            String rateStr = String.format("%4.0f",val);
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        case PCTINCOMETOOLOW:{
                            double val;
                            if (showQuarter)
                                val = bank.getLendingPolicy().getQtrChgPctRejectedLTI();
                            else
                                 val = bank.getLendingPolicy().getPctRejectedLTI();
                            String rateStr = String.format("%4.0f",val);
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        case PCTLOANTOOLARGE:{
                           double val;
                            if (showQuarter)
                                val = bank.getLendingPolicy().getQtrChgPctRejectedLoanTooLarge();
                            else
                                 val = bank.getLendingPolicy().getPctRejectedLoanTooLarge();
                            String rateStr = String.format("%4.0f",val);
                            rateStr = (rateStr + "%");
                            return rateStr;
                        }
                        default:
                            return bank.name;
                    } // end of switch
                }  // end of if
            }  // end of for
            return bank.name;
        } // end of getValueAt

        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn't implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        /*
         * Don't need to implement this method unless your table's
         * editable.
         */
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            if (col < 2) {
                return false;
            } else {
                return false;
            }
        }

        /*
         * Don't need to implement this method unless your table's
         * data can change.
         */
        public void setValueAt(Object value, int row, int col) {
            //data[row][col] = value;
            //fireTableCellUpdated(row, col);
        }
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        bankInfoTable = new javax.swing.JTable();
        entireSimulationButton = new javax.swing.JRadioButton();
        previousQuarterButton = new javax.swing.JRadioButton();

        setTitle("Bank Summary");

        jScrollPane1.setHorizontalScrollBar(null);

        bankInfoTable.setFont(new java.awt.Font("Lucida Grande", 0, 10)); // NOI18N
        bankInfoTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        bankInfoTable.setName("Bank Summary"); // NOI18N
        bankInfoTable.setOpaque(false);
        jScrollPane1.setViewportView(bankInfoTable);

        entireSimulationButton.setText("Entire simulation");
        entireSimulationButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                entireSimulationButtonActionPerformed(evt);
            }
        });

        previousQuarterButton.setText("Change in most recently completed quarter");
        previousQuarterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                previousQuarterButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(entireSimulationButton)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(previousQuarterButton)
                .addContainerGap(33, Short.MAX_VALUE))
            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 476, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(entireSimulationButton)
                    .add(previousQuarterButton))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 371, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void entireSimulationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_entireSimulationButtonActionPerformed
        // TODO add your handling code here:
        if (entireSimulationButton.isSelected())
            showQuarter(false);
        else
            showQuarter(true);
}//GEN-LAST:event_entireSimulationButtonActionPerformed

    private void previousQuarterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_previousQuarterButtonActionPerformed
        // TODO add your handling code here:
        if (previousQuarterButton.isSelected())
            showQuarter(true);
        else
            showQuarter(false);
    }//GEN-LAST:event_previousQuarterButtonActionPerformed

    /**
    * @param args the command line arguments
    */
    /*
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BankSummary().setVisible(true);
            }
        });
    }
    */

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTable bankInfoTable;
    private javax.swing.JRadioButton entireSimulationButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JRadioButton previousQuarterButton;
    // End of variables declaration//GEN-END:variables

}
